﻿//-----------------------------------------------------------------------
// <copyright file="WorkItems.cs" company="Microsoft Corporation">
//     Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
//-----------------------------------------------------------------------
namespace VisualStudioOnlineOData
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Linq;

    /// <summary>
    ///
    /// </summary>
    public class WorkItems
    {
        private static int counter = 0;

        /// <summary>
        /// Gets the work items asynchronous.
        /// </summary>
        /// <param name="credentials">The credentials.</param>
        /// <param name="queryId">The query identifier.</param>
        /// <param name="onSuccessfulResult">The on successful result.</param>
        /// <returns></returns>
        public static async Task<IEnumerable<Models.WorkItem>> GetWorkItemsAsync(Credentials credentials, string queryId, Action<XDocument> onSuccessfulResult = null)
        {
            var result = new List<Models.WorkItem>();
            counter = 0;
            await GetWorkItemsAsync(credentials, "https://tfsodata.visualstudio.com/DefaultCollection/Queries('" + queryId + "')/WorkItems", result);
            foreach (var item in result)
            {
                item.Content.Properties.LoadMetaInfo();
            }

            if (onSuccessfulResult != null)
            {
                var document = new XDocument();
                var root = new XElement("root");
                foreach (var item in result)
                {
                    root.Add(item.ToXML());
                }

                document.Add(root);
                onSuccessfulResult(document);
            }

            return result;
        }

        /// <summary>
        /// Updates the specified URI.
        /// </summary>
        /// <param name="uri">The URI.</param>
        /// <param name="credentials">The credentials.</param>
        /// <param name="description">The description.</param>
        /// <returns></returns>
        public static async Task<bool> Update(string uri, Credentials credentials, string state, string description)
        {
            using (var handler = new HttpClientHandler())
            {
                handler.Credentials = new NetworkCredential(credentials.Account + "\\" + credentials.Username, credentials.Password);
                using (var client = new HttpClient(handler))
                {
                    try
                    {
                        var httpContent = new StringContent(@"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>
<entry xml:base=""https://tfsodata.visualstudio.com/DefaultCollection/"" xmlns:d=""http://schemas.microsoft.com/ado/2007/08/dataservices"" xmlns:m=""http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"" xmlns=""http://www.w3.org/2005/Atom"">
  <content type=""application/xml"">
<m:properties>
<d:State>" + state + @"</d:State>
<d:Description><![CDATA[" + description + @"]]></d:Description>
</m:properties>
  </content>
</entry>", Encoding.UTF8, "application/atom+xml");
                        var response = await client.PutAsync(uri, httpContent);
                        return response.StatusCode == HttpStatusCode.NoContent;
                    }
                    catch (System.Net.Http.HttpRequestException)
                    {
                        return false;
                    }
                }
            }
        }

        private static async Task GetWorkItemsAsync(Credentials credentials, string url, IList<Models.WorkItem> result)
        {
            var httpGet = await Http.GetAsync(new Uri(url), credentials);
            if (httpGet == null)
            {
                return;
            }

            var httpResult = XMLDeserialiser.DeserialiseFromString<Models.WorkItems>(httpGet);
            if (httpResult == null || httpResult.Entry == null)
            {
                return;
            }

            foreach (var item in httpResult.Entry)
            {
                item.OriginalPosition = counter;
                result.Add(item);
                counter++;
            }

            var next = httpResult.Link.FirstOrDefault(_ => _.Rel == "next");
            if (next != null)
            {
                await GetWorkItemsAsync(credentials, next.href, result);
            }
        }
    }
}